# Introduction

The `Pane` and `Card` components are one of the most important components in Evergreen.
They are used as primitives to construct layouts and compose components.
In most cases you can use a `Pane` instead of a `div` element.

The `Pane` and `Card` components map almost directly to the `Box` from [`ui-box`](https://github.com/segmentio/ui-box).
The `Box` component is a UI Primitive component that is used as the base of many components in Evergreen.

Besides the `Pane` and `Card` component, most other components use `Box` or `Pane` as well.

## What is a React UI Primitive?

The `Box` component is a base component or "UI primitive" for creating layouts and composing components.
Many components within Evergreen use the `Box` component instead of a element such as `div` or `button`.

The `Box` component is useful because it helps with 3 common use cases

- **Create layouts without helper classes.**
- **Define components without worrying about CSS.**
- **Override single properties when using components.**

### You don’t need className

In Evergreen most of the time you don’t deal with CSS classes through the `className` property.
Instead, you write CSS properties directly onto your Evergreen components —
in most cases it will just work.

_If you know what you are doing and do need to use CSS directly, be aware that mixing
Evergreen with regular CSS might give you unexpected results._

#### When to use inline styles?

In some cases you still want to use inline styles.
The most common use cases is when you are animating a CSS property and the value is always different.

## Creating layouts with Pane

Use the `Pane` component to create your layouts.
Most CSS properties are supported on the `Pane` component.

```jsx
<Pane height={120} width={240} display="flex" alignItems="center" justifyContent="center" border="default">
  <Text>Pane</Text>
</Pane>
```

## Override single properties when using Evergreen components

Most components in Evergreen use a `Pane` or `Box` under the hood.
To add spacing, or layout properties, pass the properties straight to the component:

```jsx
<Pane display="flex" padding={16} background="tint2" borderRadius={3}>
  <Pane flex={1} alignItems="center" display="flex">
    <Heading size={600}>Left Aligned</Heading>
  </Pane>
  <Pane>
    {/* Below you can see the marginRight property on a Button. */}
    <Button marginRight={16}>Button</Button>
    <Button appearance="primary">Primary Button</Button>
  </Pane>
</Pane>
```

## Use the height property to resize components

In most cases in Evergreen you can use the `height` property on components to change the size
of a component. The text styles and padding will adjust based on the height you pass.

```jsx
<Pane display="flex">
  <TextInput width="100%" height={48} placeholder="Change my height to fit your needs." />
  <Button height={48} appearance="primary" marginLeft={16}>
    Big Button
  </Button>
</Pane>
```

### Recommendation: Use the 8px major scale grid

We recommend using values for heights, widths, margins, paddings that are always divisible by `8`.
Within Evergreen we call this the major scale.

#### Evergreen exports a utility called majorScale to help conform to the 8px major scale.

- `majorScale(1) => 8`
- `majorScale(2) => 16`
- `majorScale(3) => 24`
- `majorScale(4) => 32`
- `majorScale(5) => 40`

```jsx
<Button height={majorScale(5)}>Big Button</Button>
```

#### Use the 4px minor scale grid for values under 40px

We recommend only using the 4px grid for values under `40`.
Try making your designs work with the major scale first before using the minor scale.
We recommend using the minor scale primarily for spacing only when the major scale is too much.

For example: `4`, `12`, `20` are fine to use.
But avoid using `52`.

#### Evergreen exports a utility called minorScale to help conform to the 4px minor scale.

- `minorScale(1) => 4`
- `minorScale(3) => 12`
- `minorScale(5) => 20`
- `minorScale(7) => 28`
- `minorScale(9) => 36`

```jsx
<Pane>
  <Button marginRight={minorScale(3)}>Button</Button>
  <Button>Button</Button>
</Pane>
```

## Responsive layouts

Currently there is no opinionated way to construct responsive layouts in Evergreen.
In the case of responsive layouts you might want to simply use a div with a class name and use breakpoints in CSS — or potentially a CSS-in-JS solution.

In the case when you need to pass properties to a Evergreen component based on the viewport,
you can try something like react-component-queries.

## Never pass a string of text as direct children

`Pane` & `Card` don’t have text styles applied to them.
Always use a `Text`, `Heading` or other typography component as children to Panes & Cards.

# Pane component

The `Pane` component maps almost directly to the `Box` from `ui-box`.
This means you can pass everything to `Pane` that you can pass to `Box`.
Read more above to learn about this.

Because the `Pane` component directly maps to a `Box` you can pass almost any CSS property directly to the React component.

## Basic Pane example

```jsx
<Pane
  is="section"
  ref={(ref) => console.log(ref)}
  background="tint2"
  border="muted"
  marginLeft={12}
  marginY={24}
  paddingTop={12}
  paddingX={40}
  width={120}
  height={120}
  cursor="help"
  onClick={() => alert('Works just like expected')}
/>
```

## Elevation styles

`Panes` and `Cards` have a `elevation` property to give the
component a box shadow and visually elevate it from the page.

Most commonly you will be only using `0`, `1` and `2`.

```jsx
<Pane clearfix>
  <Pane
    elevation={0}
    float="left"
    backgroundColor="white"
    width={200}
    height={120}
    margin={24}
    display="flex"
    justifyContent="center"
    alignItems="center"
    flexDirection="column"
  >
    <Text>Elevation 0</Text>
    <Text size={300}>Flat Panes</Text>
  </Pane>
  <Pane
    elevation={1}
    float="left"
    width={200}
    height={120}
    margin={24}
    display="flex"
    justifyContent="center"
    alignItems="center"
    flexDirection="column"
  >
    <Text>Elevation 1</Text>
    <Text size={300}>Floating Panes</Text>
  </Pane>
</Pane>
```

### All elevation options

```jsx collapse
<Pane clearfix>
  <Pane
    elevation={0}
    float="left"
    backgroundColor="white"
    width={200}
    height={120}
    margin={24}
    display="flex"
    justifyContent="center"
    alignItems="center"
    flexDirection="column"
  >
    <Text>Elevation 0</Text>
    <Text size={300}>Flat Panes</Text>
  </Pane>
  <Pane
    elevation={1}
    float="left"
    width={200}
    height={120}
    margin={24}
    display="flex"
    justifyContent="center"
    alignItems="center"
    flexDirection="column"
  >
    <Text>Elevation 1</Text>
    <Text size={300}>Floating Panes</Text>
  </Pane>
  <Pane
    elevation={2}
    float="left"
    width={200}
    height={120}
    margin={24}
    display="flex"
    justifyContent="center"
    alignItems="center"
    flexDirection="column"
  >
    <Text>Elevation 2</Text>
    <Text size={300}>Popovers and Dropdowns</Text>
  </Pane>
  <Pane
    elevation={3}
    float="left"
    width={200}
    height={120}
    margin={24}
    display="flex"
    justifyContent="center"
    alignItems="center"
    flexDirection="column"
  >
    <Text>Elevation 3</Text>
    <Text size={300}>Toasts</Text>
  </Pane>
  <Pane
    elevation={4}
    float="left"
    width={200}
    height={120}
    margin={24}
    display="flex"
    justifyContent="center"
    alignItems="center"
    flexDirection="column"
  >
    <Text>Elevation 4</Text>
    <Text size={300}>Dialog</Text>
  </Pane>
</Pane>
```

## Background colors

The `background` property on a `Pane` is special.
You have access to all of the colors defined in the theme objects.

### Use tint1 and tint2 for slight gray backgrounds

```jsx
<Pane>
  <Pane background="tint1" padding={24} marginBottom={16}>
    <Text>tint1</Text>
  </Pane>
  <Pane background="tint2" padding={24}>
    <Text>tint2</Text>
  </Pane>
</Pane>
```

## Border colors

The `border` property on a `Pane` is special.
You have access to all of the colors defined in the theme objects.

Possible values are `default` or `muted`. If you pass the `border` property as a boolean
it will use the `default` option.

```jsx
<Pane clearfix>
  <Pane border width={120} height={80} marginRight={16} float="left" />
  <Pane border="default" width={120} height={80} marginRight={16} float="left" />
  <Pane border="muted" width={120} height={80} marginRight={16} float="left" />
</Pane>
```

All border sides are supported on a `Pane`

```jsx
<Pane borderTop borderRight borderLeft borderBottom width={120} height={80} />
```

# Card component

The `Card` component is exactly the same as the `Pane` component.
The only difference is that the `Card` has a `borderRadius` by default.
